import React from 'react';
import PropTypes from 'prop-types';
import { FlatList, View, RefreshControl, ActivityIndicator, StyleSheet } from 'react-native';
import { Label } from "./Component"
import { Lt, Color, Jx } from './Jx';

const LOAD_MOUNT = 1, LOAD_ADD = 1, LOAD_REFRESH = 1, LOAD_CONTROL = 1;
// 加载列表封装 上拉刷新, 下拉加载
export class Flist extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            array : [],
            freshing : true,
            adding : true,
        }
        this.array = [];
        this.arrayShow = [];
        this.clear();
        this.flist = null;

        this.onItem = this.onItem.bind(this);
        this.refreshControl = this.refresh.bind(this, true);
        this.onAdd = this.onAdd.bind(this);
        this.foot = this.foot.bind(this);
        this.add = this.add.bind(this);
        this.add1 = this.add1.bind(this);
    }

    componentWillMount(){
        // 渲染元素有变化->重新计算列表高度->重新判断onEndReached条件->触发onEndReached回调
        this.onLoad({LOAD_MOUNT});
    }

    static propTypes = {
        maxpp : PropTypes.number.isRequired,
        countpp : PropTypes.number.isRequired,
        endStr : PropTypes.string.isRequired,
    }

    static defaultProps = {
        maxpp : 10,
        countpp : 10,
        endStr : "没有更多",
    }

    clear(){
        this.array.length = 0;
        this.arrayShow.length = 0;
        this.isLoadEnd = false;
        this.page = 0;
    }

    show(count){
        let i1 = this.arrayShow.length;
        for(let i = 0; i < count; ++i){
            this.arrayShow.push(this.array[i1 + i]);
        }
        this.onShow(this.arrayShow);
    }

    static toPagination(page, maxpp){
        return {pageNo:page + 1, pageSize:maxpp};
    }

    static toPageStr(page, maxpp){
        return "pageNo=" + (page + 1) + "&pageSize=" + maxpp;
    }

    onLoad(cfg){
        // console.log("Flist列表onLoad: " + Jx.stringify(cfg));
        const { onLoad, maxpp } = this.props;
        const page = this.page;
        ++this.page;
        onLoad && onLoad({
            maxpp, 
            page,
            add : this.add,
            add1 : this.add1,
            pagination : Flist.toPagination(page, maxpp),
            pageStr : Flist.toPageStr(page, maxpp),
        });
        
    }

    clearStateArray(){
        this.onShow([])
    }

    refresh(fromControl){
        this.clear();
        this.setState({
            freshing : true,
            adding:true,
        });
        if(fromControl){
            this.onLoad({LOAD_CONTROL});
        }else{
            this.onLoad({LOAD_REFRESH});
        }
    }

    toTop(){
        this.flist && this.flist.scrollToOffset({offset:0, animated:false});
    }

    onAdd(){
        // console.log("Flist列表onAdd: ");
        // 不然一直请求 3456789页
        if(!this.state.adding){
            return;
        }
        if((this.array.length - this.arrayShow.length) >= this.props.countpp){
            this.show(this.props.countpp);
            return;
        }
        this.onLoad({LOAD_ADD});
    }

    showInner(){
        const count = this.array.length - this.arrayShow.length;
        if(count >= this.props.countpp){
            this.show(this.props.countpp);
        } else {
            this.show(count);
        }
    }

    add1(e){
        // 肯定不是终结者
        this.setState({
            freshing : false,
        });
        this.array.push(e);
        this.showInner();
    }

    add(arr, totalCount){
        this.setState({
            freshing : false,
        });
        if(!arr){
            this.isLoadEnd = true;
        }else if(arr.length < 1){
            // < maxpp
            // totalCount
            this.isLoadEnd = true;
        }else {
            this.array = this.array.concat(arr);
            // undefine 0 都不成立
            if(this.array.length == totalCount){
                this.isLoadEnd = true;
            }
        }
        this.showInner();
    }

    onItem(item){
        const { onItem } = this.props;
        return onItem ? onItem(item) : null;
    }
    onShow(array){
        this.setState({
            // PureComponent
            array : [].concat(array),
        })
        if(this.isLoadEnd && array.length == this.array.length){
            this.setState({ 
                adding : false,
            });
        }
        const { onShow } = this.props;
        onShow && onShow(array);
    }
    render() {
        const {style, countpp, maxpp, endStr, onLoad, onItem, onShow, ...other } = this.props
        const { array, freshing } = this.state;
        return <FlatList
            ref={r=>this.flist=r}
            style = {style}
            //设置数据
            data={array}
            keyExtractor={(item, index)=>index.toString()}
            renderItem = {this.onItem}
            refreshControl={<RefreshControl
                //Android下只有一个 colors 是转圈的颜色
                colors={['#d11', '#000']}
                //ios 下 可以设置标题，转圈颜色，标题颜色
                title={'Loading...'}
                tintColor={'#d11'}
                titleColor={'#d11'}
                //刷新状态 false:隐藏，true:显示
                refreshing={freshing}
                //刷新触发的后执行的方法
                onRefresh={this.refreshControl}
            />}
            //定义加载更多控件
            ListFooterComponent={this.foot}
            //设置触发 onEndReached 的距离
            onEndReachedThreshold = {0.5}
            //触发加载更多的后执行的方法
            onEndReached={this.onAdd}
            ListEmptyComponent = {ViewFootEmpty(freshing ? "" : endStr)}
            {...other}
        />
    }

    foot() {
        const {adding, array, freshing} = this.state;
        const { endStr } = this.props;
        if(!freshing){
            if(adding){
                return <View style = {styles.foot}><ActivityIndicator size={'large'} animating={ true }/></View>
            }
            if(array.length > 0){
                return ViewFootEmpty(endStr);
            }
        }
        return <View/>;
    }
}

function ViewFootEmpty(endStr){
    return <View style = {styles.foot}><Label style={{ color: Color.c9 }}>{endStr}</Label></View>
}

const styles = StyleSheet.create({
    foot:{
        flexDirection:"row", 
        justifyContent:"center", 
        alignItems:"center", 
        padding:Lt.pad,
    }
})